/*
 * SimplificationFunction.java
 *
 * Created on den 22 april 2007, 22:42
 *
 * To change this template, choose Tools | Template Manager
 * and open the template in the editor.
 */

package grex.fitnessfunctions;

import grex.GP;
import grex.Options;
import grex.Data.Prediction;
import grex.Nodes.Node;
import grex.Nodes.GeneException;
import grex.Nodes.IContinuousOperator;
import grex.Nodes.If;

import java.io.Serializable;
import java.util.concurrent.CopyOnWriteArrayList;

/**
 *
 * @author rik
 */
public class AlternativeSolutionFitness implements IFitnessFunction, Serializable{

    /** Creates a new instance of SimplificationFunction */
    public CopyOnWriteArrayList<Node> splits;


    public AlternativeSolutionFitness() {
        splits = new CopyOnWriteArrayList<Node>();
    }

    public double calcFitness(GP gp) throws GeneException {

        GP org = gp.getOptions().getGp();
        Options ops = gp.getOptions();


     /*   if(ops.get getConSplits()==null){
            ops.setCatSplits(catSplits);
            ops.setConSplits(conSplits);
            init(org.getHead());
        }*/
        double trainFitness=0,valFitness=0;
        gp.train();
        for(Prediction p:gp.getPcTrain().values())
            if(p.getPrediction()==p.getTargetValue())
                trainFitness++;

        trainFitness=1-trainFitness/gp.getPcTrain().size();
        //double like = compareGPs(gp.getHead(),org.getHead());
        //System.out.println("likeness:" + likeness);
        //System.out.println(org.getFormatedTree());
        //System.out.println(gp.getFormatedTree());
        double like = likeness(gp.getHead());
        //System.out.println("Likeness" + like+"\n");
        return 10000*trainFitness + gp.getNrOfNodes() + like;
        //return trainFitness*100 -gp.getLength();
    }

    private double likeness(Node g){
        int points = 0;
        System.out.println("Outdated!!!! Revise!!!");
        if(g instanceof If){
            Node split = g.getChildren()[0];
            if(split instanceof IContinuousOperator){
         //      if(conSplits.contains(g))
                   points++;
            }else{
       //        if(catSplits.contains(g))
                   points++;
            }
            points += likeness(g.getChildren()[1]);
            points += likeness(g.getChildren()[2]);
        }
        return points;
    }
    private void init(Node g){
        if(g instanceof If){
            Node split = g.getChildren()[0];
            if(split instanceof IContinuousOperator)
    //            conSplits.add(g);
       //     else if (split instanceof ICategoricalOperator)
     //           catSplits.add(g);
            init(g.getChildren()[1]);
            init(g.getChildren()[2]);
        }

    }

    private double compareGPs(Node g1,Node g2){
        if(!g1.equals(g2))
            return 0;
        int points = 1;
        if(g1 instanceof If){
            points += compareGPs(g1.getChildren()[1],g2.getChildren()[1]);
            points += compareGPs(g1.getChildren()[2],g2.getChildren()[2]);
        }
        return points;
    }



}
